#!/bin/bash

function print_header() {
clear

cat <<"EOF"
---------------------------------------
 ____  _                  
|  _ \| | __ _ _ __   ___ 
| |_) | |/ _` | '_ \ / _ \
|  __/| | (_| | | | |  __/
|_|   |_|\__,_|_| |_|\___|

---------------------------------------
Project management tool from the future
---------------------------------------

EOF
}
function update_env_file() {
    config_file=$1
    key=$2
    value=$3

    # Check if the config file exists
    if [ ! -f "$config_file" ]; then
        echo "Config file not found. Creating a new one..." >&2
        sudo touch "$config_file"
    fi

    # Check if the key already exists in the config file
    if sudo grep "^$key=" "$config_file"; then
        sudo awk -v key="$key" -v value="$value" -F '=' '{if ($1 == key) $2 = value} 1' OFS='=' "$config_file" | sudo tee "$config_file.tmp" > /dev/null
        sudo mv "$config_file.tmp" "$config_file" &> /dev/null
    else
        # sudo echo "$key=$value" >> "$config_file"
        echo -e "$key=$value" | sudo tee -a "$config_file" > /dev/null
    fi
}
function read_env_file() {
    config_file=$1
    key=$2

    # Check if the config file exists
    if [ ! -f "$config_file" ]; then
        echo "Config file not found. Creating a new one..." >&2
        sudo touch "$config_file"
    fi

    # Check if the key already exists in the config file
    if sudo grep -q "^$key=" "$config_file"; then
        value=$(sudo awk -v key="$key" -F '=' '{if ($1 == key) print $2}' "$config_file")
        echo "$value"
    else
        echo ""
    fi
}
function update_config() {
    config_file="$PLANE_INSTALL_DIR/config.env"
    update_env_file $config_file $1 $2
}
function read_config() {
    config_file="$PLANE_INSTALL_DIR/config.env"
    read_env_file $config_file $1
}
function update_env() {
    config_file="$PLANE_INSTALL_DIR/.env"
    update_env_file $config_file $1 $2
}
function read_env() {
    config_file="$PLANE_INSTALL_DIR/.env"
    read_env_file $config_file $1
}
function show_message() {
    print_header

    if [ "$2" == "replace_last_line" ]; then
        PROGRESS_MSG[-1]="$1"
    else
        PROGRESS_MSG+=("$1")
    fi

    for statement in "${PROGRESS_MSG[@]}"; do
        echo "$statement"
    done

}
function prepare_environment() {
    show_message "Prepare Environment..." >&2

    show_message "- Updating OS with required tools ✋"  >&2
    sudo "$PACKAGE_MANAGER" update -y
    # sudo "$PACKAGE_MANAGER" upgrade -y

    local required_tools=("curl" "awk" "wget" "nano" "dialog" "git" "uidmap" "jq")

    for tool in "${required_tools[@]}"; do
        if ! command -v $tool &> /dev/null; then
            sudo "$PACKAGE_MANAGER" install -y $tool
        fi
    done

    show_message "- OS Updated ✅" "replace_last_line"  >&2

    # Install Docker if not installed
    if ! command -v docker &> /dev/null; then
        show_message "- Installing Docker ✋"  >&2
        # curl -o- https://get.docker.com | bash - 

        if [ "$PACKAGE_MANAGER" == "yum" ]; then
            sudo $PACKAGE_MANAGER install -y yum-utils
            sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo &> /dev/null
        elif [ "$PACKAGE_MANAGER" == "apt-get" ]; then
            # Add Docker's official GPG key:
            sudo $PACKAGE_MANAGER update 
            sudo $PACKAGE_MANAGER install ca-certificates curl &> /dev/null
            sudo install -m 0755 -d /etc/apt/keyrings &> /dev/null
            sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc &> /dev/null
            sudo chmod a+r /etc/apt/keyrings/docker.asc &> /dev/null

            # Add the repository to Apt sources:
            echo \
                "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
                $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
                sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
            
            sudo $PACKAGE_MANAGER update
        fi

        sudo $PACKAGE_MANAGER install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y

        show_message "- Docker Installed ✅" "replace_last_line"  >&2
    else
        show_message "- Docker is already installed ✅"  >&2
    fi

    update_config "PLANE_ARCH" "$CPU_ARCH"
    update_config "DOCKER_VERSION" "$(docker -v | awk '{print $3}' | sed 's/,//g')"
    update_config "PLANE_DATA_DIR" "$DATA_DIR"
    update_config "PLANE_LOG_DIR" "$LOG_DIR"

    # echo "TRUE"
    echo "Environment prepared successfully ✅"
    show_message "Environment prepared successfully ✅" >&2
    show_message "" >&2
    return 0
}
function download_plane() {
    # Download Docker Compose File from github url 
    show_message "Downloading Plane Setup Files ✋"  >&2
    sudo curl -H 'Cache-Control: no-cache, no-store' \
        -s -o $PLANE_INSTALL_DIR/docker-compose.yaml  \
        https://raw.githubusercontent.com/$CODE_REPO/$DEPLOY_BRANCH/deploy/selfhost/docker-compose.yml?token=$(date +%s) 

    sudo curl -H 'Cache-Control: no-cache, no-store' \
        -s -o $PLANE_INSTALL_DIR/variables-upgrade.env \
        https://raw.githubusercontent.com/$CODE_REPO/$DEPLOY_BRANCH/deploy/selfhost/variables.env?token=$(date +%s) 

    # if .env does not exists rename variables-upgrade.env to .env
    if [ ! -f "$PLANE_INSTALL_DIR/.env" ]; then
        sudo mv $PLANE_INSTALL_DIR/variables-upgrade.env $PLANE_INSTALL_DIR/.env
    fi

    show_message "Plane Setup Files Downloaded ✅" "replace_last_line"  >&2
    show_message ""  >&2

    echo "PLANE_DOWNLOADED"
    return 0
}
function printUsageInstructions() {
    show_message ""  >&2
    show_message "----------------------------------" >&2
    show_message "Usage Instructions" >&2
    show_message "----------------------------------" >&2
    show_message ""  >&2
    show_message "To use the Plane Setup utility, use below commands" >&2
    show_message "" >&2

    show_message "Usage: plane-app [OPTION]" >&2
    show_message "" >&2
    show_message "  start                       Start Server" >&2
    show_message "  stop                        Stop Server" >&2
    show_message "  restart                     Restart Server" >&2
    show_message "" >&2
    show_message "other options" >&2
    show_message "  -i, --install               Install Plane" >&2
    show_message "  -c, --configure             Configure Plane" >&2
    show_message "  -up, --upgrade              Upgrade Plane" >&2
    show_message "  -un, --uninstall            Uninstall Plane" >&2
    show_message "  -ui, --update-installer     Update Plane Installer" >&2
    show_message "  -h, --help                  Show help" >&2
    show_message "" >&2
    show_message ""  >&2
    show_message "Application Data is stored in mentioned folders" >&2
    show_message "  - DB Data: $DATA_DIR/postgres" >&2
    show_message "  - Redis Data: $DATA_DIR/redis" >&2
    show_message "  - Minio Data: $DATA_DIR/minio" >&2
    show_message "" >&2
    show_message "" >&2
    show_message "----------------------------------" >&2
    show_message ""  >&2
}
function build_local_image() {
    show_message "- Downloading Plane Source Code ✋" >&2
    REPO=https://github.com/$CODE_REPO.git
    CURR_DIR=$PWD
    PLANE_TEMP_CODE_DIR=$PLANE_INSTALL_DIR/temp
    sudo rm -rf $PLANE_TEMP_CODE_DIR > /dev/null

    sudo git clone $REPO $PLANE_TEMP_CODE_DIR  --branch $DEPLOY_BRANCH --single-branch -q > /dev/null

    sudo cp $PLANE_TEMP_CODE_DIR/deploy/selfhost/build.yml $PLANE_TEMP_CODE_DIR/build.yml

    show_message "- Plane Source Code Downloaded ✅" "replace_last_line" >&2
    
    show_message "- Building Docker Images ✋" >&2
    sudo docker compose --env-file=$PLANE_INSTALL_DIR/.env -f $PLANE_TEMP_CODE_DIR/build.yml build --no-cache
}
function check_for_docker_images() {
    show_message "" >&2
    # show_message "Building Plane Images" >&2
    
    CURR_DIR=$(pwd)
    
    if [ "$DEPLOY_BRANCH" == "master" ]; then
        update_env "APP_RELEASE" "latest"
        export APP_RELEASE=latest
    else
        update_env "APP_RELEASE" "$DEPLOY_BRANCH"
        export APP_RELEASE=$DEPLOY_BRANCH    
    fi

    if [ $USE_GLOBAL_IMAGES == 1 ]; then
        # show_message "Building Plane Images for $CPU_ARCH is not required. Skipping... ✅" "replace_last_line" >&2
        export DOCKERHUB_USER=makeplane
        update_env "DOCKERHUB_USER" "$DOCKERHUB_USER"
        update_env "PULL_POLICY" "always"
        echo "Building Plane Images for $CPU_ARCH is not required. Skipping..."
    else
        export DOCKERHUB_USER=myplane
        show_message "Building Plane Images for $CPU_ARCH " >&2
        update_env "DOCKERHUB_USER" "$DOCKERHUB_USER"
        update_env "PULL_POLICY" "never"

        build_local_image

        sudo rm -rf $PLANE_INSTALL_DIR/temp > /dev/null

        show_message "- Docker Images Built ✅" "replace_last_line" >&2
        sudo cd $CURR_DIR
    fi

    sudo sed -i "s|- pgdata:|- $DATA_DIR/postgres:|g" $PLANE_INSTALL_DIR/docker-compose.yaml
    sudo sed -i "s|- redisdata:|- $DATA_DIR/redis:|g" $PLANE_INSTALL_DIR/docker-compose.yaml
    sudo sed -i "s|- uploads:|- $DATA_DIR/minio:|g" $PLANE_INSTALL_DIR/docker-compose.yaml

    show_message "Downloading Plane Images for $CPU_ARCH ✋" >&2
    sudo docker compose -f $PLANE_INSTALL_DIR/docker-compose.yaml --env-file=$PLANE_INSTALL_DIR/.env pull
    show_message "Plane Images Downloaded ✅" "replace_last_line" >&2
}
function configure_plane() {
    show_message "" >&2
    show_message "Configuring Plane" >&2
    show_message "" >&2

    exec 3>&1

    nginx_port=$(read_env "NGINX_PORT")
    domain_name=$(read_env "DOMAIN_NAME")
    upload_limit=$(read_env "FILE_SIZE_LIMIT")

    NGINX_SETTINGS=$(dialog \
        --ok-label "Next" \
        --cancel-label "Skip" \
        --backtitle "Plane Configuration" \
        --title "Nginx Settings" \
        --form "" \
        0 0 0 \
        "Port:"                   1 1	        "${nginx_port:-80}"            1 10 50 0 \
        "Domain:"                 2 1	        "${domain_name:-localhost}"     2 10 50 0 \
        "Upload Limit:"           3 1	        "${upload_limit:-5242880}"       3 10 15 0 \
    2>&1 1>&3)

    save_nginx_settings=0
    if [ $? -eq 0 ]; then
        save_nginx_settings=1
        nginx_port=$(echo "$NGINX_SETTINGS" | sed -n 1p)
        domain_name=$(echo "$NGINX_SETTINGS" | sed -n 2p)
        upload_limit=$(echo "$NGINX_SETTINGS" | sed -n 3p)
    fi


    # smtp_host=$(read_env "EMAIL_HOST")
    # smtp_user=$(read_env "EMAIL_HOST_USER")
    # smtp_password=$(read_env "EMAIL_HOST_PASSWORD")
    # smtp_port=$(read_env "EMAIL_PORT")
    # smtp_from=$(read_env "EMAIL_FROM")
    # smtp_tls=$(read_env "EMAIL_USE_TLS")
    # smtp_ssl=$(read_env "EMAIL_USE_SSL")

    # SMTP_SETTINGS=$(dialog \
    #     --ok-label "Next" \
    #     --cancel-label "Skip" \
    #     --backtitle "Plane Configuration" \
    #     --title "SMTP Settings" \
    #     --form "" \
    #     0 0 0 \
    #     "Host:"        1 1	  "$smtp_host" 	              1 10 80 0 \
    #     "User:"        2 1	  "$smtp_user" 	              2 10 80 0 \
    #     "Password:"    3 1	  "$smtp_password" 	              3 10 80 0 \
    #     "Port:"        4 1	  "${smtp_port:-587}"               4 10 5 0 \
    #     "From:"        5 1	  "${smtp_from:-Mailer <mailer@example.com>}"               5 10 80 0 \
    #     "TLS:"         6 1	  "${smtp_tls:-1}"                 6 10 1 1 \
    #     "SSL:"         7 1	  "${smtp_ssl:-0}"                 7 10 1 1 \
    # 2>&1 1>&3)

    # save_smtp_settings=0
    # if [ $? -eq 0 ]; then
    #     save_smtp_settings=1
    #     smtp_host=$(echo "$SMTP_SETTINGS" | sed -n 1p)
    #     smtp_user=$(echo "$SMTP_SETTINGS" | sed -n 2p)
    #     smtp_password=$(echo "$SMTP_SETTINGS" | sed -n 3p)
    #     smtp_port=$(echo "$SMTP_SETTINGS" | sed -n 4p)
    #     smtp_from=$(echo "$SMTP_SETTINGS" | sed -n 5p)
    #     smtp_tls=$(echo "$SMTP_SETTINGS" | sed -n 6p)
    # fi
    external_pgdb_url=$(dialog \
                    --backtitle "Plane Configuration" \
                    --title "Using External Postgres Database ?" \
                    --ok-label "Next" \
                    --cancel-label "Skip" \
                    --inputbox "Enter your external database url" \
                    8 60 3>&1 1>&2 2>&3)


    external_redis_url=$(dialog \
                    --backtitle "Plane Configuration" \
                    --title "Using External Redis Database ?" \
                    --ok-label "Next" \
                    --cancel-label "Skip" \
                    --inputbox "Enter your external redis url" \
                    8 60 3>&1 1>&2 2>&3)

    
    aws_region=$(read_env "AWS_REGION")
    aws_access_key=$(read_env "AWS_ACCESS_KEY_ID")
    aws_secret_key=$(read_env "AWS_SECRET_ACCESS_KEY")
    aws_bucket=$(read_env "AWS_S3_BUCKET_NAME")
    

    AWS_S3_SETTINGS=$(dialog \
        --ok-label "Next" \
        --cancel-label "Skip" \
        --backtitle "Plane Configuration" \
        --title "AWS S3 Bucket Configuration" \
        --form "" \
        0 0 0 \
        "Region:"         1 1	        "$aws_region"       1 10 50 0 \
        "Access Key:"     2 1	        "$aws_access_key"   2 10 50 0 \
        "Secret Key:"     3 1	        "$aws_secret_key"   3 10 50 0 \
        "Bucket:"         4 1	        "$aws_bucket"       4 10 50 0 \
    2>&1 1>&3)

    save_aws_settings=0
    if [ $? -eq 0 ]; then
        save_aws_settings=1
        aws_region=$(echo "$AWS_S3_SETTINGS" | sed -n 1p)
        aws_access_key=$(echo "$AWS_S3_SETTINGS" | sed -n 2p)
        aws_secret_key=$(echo "$AWS_S3_SETTINGS" | sed -n 3p)
        aws_bucket=$(echo "$AWS_S3_SETTINGS" | sed -n 4p)
    fi

    # display dialogbox asking for confirmation to continue
    CONFIRM_CONFIG=$(dialog \
            --title "Confirm Configuration" \
            --backtitle "Plane Configuration" \
            --yes-label "Confirm" \
            --no-label "Cancel" \
            --yesno \
            "
            save_ngnix_settings:  $save_nginx_settings
            nginx_port:           $nginx_port
            domain_name:          $domain_name
            upload_limit:         $upload_limit

            save_aws_settings:    $save_aws_settings
            aws_region:           $aws_region
            aws_access_key:       $aws_access_key
            aws_secret_key:       $aws_secret_key
            aws_bucket:           $aws_bucket

            pdgb_url:             $external_pgdb_url
            redis_url:            $external_redis_url
            " \
            0 0 3>&1 1>&2 2>&3)
    
    if [ $? -eq 0 ]; then
        if [ $save_nginx_settings == 1 ]; then
            update_env "NGINX_PORT" "$nginx_port"
            update_env "DOMAIN_NAME" "$domain_name"
            update_env "WEB_URL" "http://$domain_name"
            update_env "CORS_ALLOWED_ORIGINS" "http://$domain_name"
            update_env "FILE_SIZE_LIMIT" "$upload_limit"
        fi

        # check enable smpt settings value
        # if [ $save_smtp_settings == 1 ]; then
        #     update_env "EMAIL_HOST" "$smtp_host"
        #     update_env "EMAIL_HOST_USER" "$smtp_user"
        #     update_env "EMAIL_HOST_PASSWORD" "$smtp_password"
        #     update_env "EMAIL_PORT" "$smtp_port"
        #     update_env "EMAIL_FROM" "$smtp_from"
        #     update_env "EMAIL_USE_TLS" "$smtp_tls"
        #     update_env "EMAIL_USE_SSL" "$smtp_ssl"
        # fi

        # check enable aws settings value
        if [[ $save_aws_settings == 1 &&  $aws_access_key != ""  &&  $aws_secret_key != "" ]] ; then
            update_env "USE_MINIO" "0"
            update_env "AWS_REGION" "$aws_region"
            update_env "AWS_ACCESS_KEY_ID" "$aws_access_key"
            update_env "AWS_SECRET_ACCESS_KEY" "$aws_secret_key"
            update_env "AWS_S3_BUCKET_NAME" "$aws_bucket"
        elif [[ -z $aws_access_key || -z $aws_secret_key  ]] ; then
            update_env "USE_MINIO" "1"
            update_env "AWS_REGION" ""
            update_env "AWS_ACCESS_KEY_ID" ""
            update_env "AWS_SECRET_ACCESS_KEY" ""
            update_env "AWS_S3_BUCKET_NAME" "uploads"
        fi

        if [ "$external_pgdb_url" != "" ]; then
            update_env "DATABASE_URL" "$external_pgdb_url"
        fi
        if [ "$external_redis_url" != "" ]; then
            update_env "REDIS_URL" "$external_redis_url"
        fi
    fi

    exec 3>&-
}
function upgrade_configuration() {
    upg_env_file="$PLANE_INSTALL_DIR/variables-upgrade.env"
    # Check if the file exists
    if [ -f "$upg_env_file" ]; then
        # Read each line from the file
        while IFS= read -r line; do
            # Skip comments and empty lines
            if [[ "$line" =~ ^\s*#.*$ ]] || [[ -z "$line" ]]; then
                continue
            fi

            # Split the line into key and value
            key=$(echo "$line" | cut -d'=' -f1)
            value=$(echo "$line" | cut -d'=' -f2-)

            current_value=$(read_env "$key")

            if [ -z "$current_value" ]; then
                update_env "$key" "$value"
            fi
        done < "$upg_env_file"
    fi
}
function install() {
    show_message ""
    if [ "$(uname)" == "Linux" ]; then
        OS="linux"
        OS_NAME=$(sudo awk -F= '/^ID=/{print $2}' /etc/os-release)
        OS_NAME=$(echo "$OS_NAME" | tr -d '"')
        print_header
        if [ "$OS_NAME" == "ubuntu" ] || [ "$OS_NAME" == "debian" ] || 
                [ "$OS_NAME" == "centos" ] || [ "$OS_NAME" == "amazon" ]; then
            OS_SUPPORTED=true
            show_message "******** Installing Plane ********"
            show_message ""

            prepare_environment

            if [ $? -eq 0 ]; then
                download_plane
                if [ $? -eq 0 ]; then
                    # create_service
                    check_for_docker_images

                    last_installed_on=$(read_config "INSTALLATION_DATE")
                    # if [ "$last_installed_on" == "" ]; then
                    #     configure_plane
                    # fi
                    
                    update_env "NGINX_PORT" "80"
                    update_env "DOMAIN_NAME" "$MY_IP"
                    update_env "WEB_URL" "http://$MY_IP"
                    update_env "CORS_ALLOWED_ORIGINS" "http://$MY_IP"

                    update_config "INSTALLATION_DATE" "$(date '+%Y-%m-%d')"
                    
                    if command -v crontab &> /dev/null; then
                        sudo touch /etc/cron.daily/makeplane
                        sudo chmod +x /etc/cron.daily/makeplane
                        sudo echo "0 2 * * * root /usr/local/bin/plane-app --upgrade" > /etc/cron.daily/makeplane
                        sudo crontab /etc/cron.daily/makeplane 
                    fi

                    show_message "Plane Installed Successfully ✅"
                    show_message ""
                else
                    show_message "Download Failed ❌"
                    exit 1
                fi
            else
                show_message "Initialization Failed ❌"
                exit 1
            fi
            
        else
            OS_SUPPORTED=false
            PROGRESS_MSG="❌❌ Unsupported OS Varient Detected : $OS_NAME ❌❌"
            show_message ""
            exit 1
        fi
    else
        PROGRESS_MSG="❌❌❌ Unsupported OS Detected : $(uname) ❌❌❌"
        show_message ""
        exit 1
    fi
}
function upgrade() {
    print_header
    if [ "$(uname)" == "Linux" ]; then
        OS="linux"
        OS_NAME=$(sudo awk -F= '/^ID=/{print $2}' /etc/os-release)
        OS_NAME=$(echo "$OS_NAME" | tr -d '"')
        if [ "$OS_NAME" == "ubuntu" ] || [ "$OS_NAME" == "debian" ] || 
                [ "$OS_NAME" == "centos" ] || [ "$OS_NAME" == "amazon" ]; then

            OS_SUPPORTED=true
            show_message "******** Upgrading Plane ********"
            show_message ""

            prepare_environment

            if [ $? -eq 0 ]; then
                stop_server
                download_plane
                if [ $? -eq 0 ]; then
                    check_for_docker_images
                    upgrade_configuration
                    update_config "UPGRADE_DATE" "$(date)"

                    start_server

                    show_message ""
                    show_message "Plane Upgraded Successfully ✅"
                    show_message ""
                    printUsageInstructions
                else
                    show_message "Download Failed ❌"
                    exit 1
                fi
            else
                show_message "Initialization Failed ❌"
                exit 1
            fi
        else
            PROGRESS_MSG="❌❌ Unsupported OS Varient Detected : $OS_NAME ❌❌"
            show_message ""
            exit 1
        fi
    else
        PROGRESS_MSG="❌❌❌ Unsupported OS Detected : $(uname) ❌❌❌"
        show_message ""
        exit 1
    fi
}
function uninstall() {
    print_header
    if [ "$(uname)" == "Linux" ]; then
        OS="linux"
        OS_NAME=$(awk -F= '/^ID=/{print $2}' /etc/os-release)
        OS_NAME=$(echo "$OS_NAME" | tr -d '"')
        if [ "$OS_NAME" == "ubuntu" ] || [ "$OS_NAME" == "debian" ] || 
                [ "$OS_NAME" == "centos" ] || [ "$OS_NAME" == "amazon" ]; then

            OS_SUPPORTED=true
            show_message "******** Uninstalling Plane ********"
            show_message ""

            stop_server

            if ! [ -x "$(command -v docker)" ]; then
                echo "DOCKER_NOT_INSTALLED" &> /dev/null
            else
                # Ask of user input to confirm uninstall docker ?
                CONFIRM_DOCKER_PURGE=$(dialog --title "Uninstall Docker" --defaultno --yesno "Are you sure you want to uninstall docker ?" 8 60 3>&1 1>&2 2>&3)
                if [ $? -eq 0 ]; then
                    show_message "- Uninstalling Docker ✋"
                    sudo docker images -q | xargs -r sudo docker rmi -f &> /dev/null
                    sudo "$PACKAGE_MANAGER" remove -y docker-engine docker docker.io docker-ce docker-ce-cli docker-compose-plugin &> /dev/null
                    sudo "$PACKAGE_MANAGER" autoremove -y docker-engine docker docker.io docker-ce docker-compose-plugin &> /dev/null
                    show_message "- Docker Uninstalled ✅" "replace_last_line" >&2
                fi
            fi

            sudo rm $PLANE_INSTALL_DIR/.env &> /dev/null
            sudo rm $PLANE_INSTALL_DIR/variables-upgrade.env &> /dev/null
            sudo rm $PLANE_INSTALL_DIR/config.env &> /dev/null
            sudo rm $PLANE_INSTALL_DIR/docker-compose.yaml &> /dev/null

            if command -v crontab &> /dev/null; then
                sudo crontab -r &> /dev/null
                sudo rm /etc/cron.daily/makeplane &> /dev/null
            fi
            
            # rm -rf $PLANE_INSTALL_DIR &> /dev/null
            show_message "- Configuration Cleaned ✅"

            show_message ""
            show_message "******** Plane Uninstalled ********"
            show_message ""
            show_message ""
            show_message "Plane Configuration Cleaned with some exceptions"
            show_message "- DB Data: $DATA_DIR/postgres"
            show_message "- Redis Data: $DATA_DIR/redis"
            show_message "- Minio Data: $DATA_DIR/minio"
            show_message ""
            show_message ""
            show_message "Thank you for using Plane. We hope to see you again soon."
            show_message ""
            show_message ""
        else
            PROGRESS_MSG="❌❌ Unsupported OS Varient Detected : $OS_NAME ❌❌"
            show_message ""
            exit 1
        fi
    else
        PROGRESS_MSG="❌❌❌ Unsupported OS Detected : $(uname) ❌❌❌"
        show_message ""
        exit 1
    fi
}
function start_server() {
    docker_compose_file="$PLANE_INSTALL_DIR/docker-compose.yaml"
    env_file="$PLANE_INSTALL_DIR/.env"
    # check if both the files exits 
    if [ -f "$docker_compose_file" ] && [ -f "$env_file" ]; then
        show_message "Starting Plane Server ($APP_RELEASE) ✋"
        sudo docker compose -f $docker_compose_file --env-file=$env_file up -d

        # Wait for containers to be running
        echo "Waiting for containers to start..."
        while ! sudo docker compose -f "$docker_compose_file" --env-file="$env_file" ps --services --filter "status=running" --quiet | grep -q "."; do
            sleep 1
        done
        # wait for migrator container to exit with status 0 before starting the application
        migrator_container_id=$(sudo docker container ls -aq -f "name=plane-migrator")

        # if migrator container is running, wait for it to exit
        if [ -n "$migrator_container_id" ]; then
            while sudo docker inspect --format='{{.State.Status}}' $migrator_container_id | grep -q "running"; do
                show_message "Waiting for Plane Server ($APP_RELEASE) to start...✋ (Migrator in progress)" "replace_last_line" >&2
                sleep 1
            done
        fi

        # if migrator exit status is not 0, show error message and exit
        if [ -n "$migrator_container_id" ]; then
            migrator_exit_code=$(sudo docker inspect --format='{{.State.ExitCode}}' $migrator_container_id)
            if [ $migrator_exit_code -ne 0 ]; then
                # show_message "Migrator failed with exit code $migrator_exit_code ❌" "replace_last_line" >&2
                show_message "Plane Server failed to start ❌" "replace_last_line" >&2
                stop_server
                exit 1
            fi
        fi

        api_container_id=$(sudo docker container ls -q -f "name=plane-api")
        while ! sudo docker logs $api_container_id 2>&1 | grep -i "Application startup complete";
        do
            show_message "Waiting for Plane Server ($APP_RELEASE) to start...✋ (API starting)" "replace_last_line" >&2
            sleep 1
        done
        show_message "Plane Server Started ($APP_RELEASE) ✅" "replace_last_line" >&2
        show_message "---------------------------------------------------------------" >&2
        show_message "Access the Plane application at http://$MY_IP" >&2
        show_message "---------------------------------------------------------------" >&2

    else
        show_message "Plane Server not installed. Please install Plane first ❌" "replace_last_line" >&2
    fi
}
function stop_server() {
    docker_compose_file="$PLANE_INSTALL_DIR/docker-compose.yaml"
    env_file="$PLANE_INSTALL_DIR/.env"
    # check if both the files exits 
    if [ -f "$docker_compose_file" ] && [ -f "$env_file" ]; then
        show_message "Stopping Plane Server ($APP_RELEASE) ✋"
        sudo docker compose -f $docker_compose_file --env-file=$env_file down
        show_message "Plane Server Stopped ($APP_RELEASE) ✅" "replace_last_line" >&2
    else
        show_message "Plane Server not installed [Skipping] ✅" "replace_last_line" >&2
    fi
}
function restart_server() {
    docker_compose_file="$PLANE_INSTALL_DIR/docker-compose.yaml"
    env_file="$PLANE_INSTALL_DIR/.env"
    # check if both the files exits 
    if [ -f "$docker_compose_file" ] && [ -f "$env_file" ]; then
        show_message "Restarting Plane Server ($APP_RELEASE) ✋"
        sudo docker compose -f $docker_compose_file --env-file=$env_file restart
        show_message "Plane Server Restarted ($APP_RELEASE) ✅" "replace_last_line" >&2
    else
        show_message "Plane Server not installed. Please install Plane first ❌" "replace_last_line" >&2
    fi
}
function show_help() {
    # print_header
    show_message "Usage: plane-app [OPTION]" >&2
    show_message "" >&2
    show_message "  start                       Start Server" >&2
    show_message "  stop                        Stop Server" >&2
    show_message "  restart                     Restart Server" >&2
    show_message "" >&2
    show_message "other options" >&2
    show_message "  -i, --install               Install Plane" >&2
    show_message "  -c, --configure             Configure Plane" >&2
    show_message "  -up, --upgrade              Upgrade Plane" >&2
    show_message "  -un, --uninstall            Uninstall Plane" >&2
    show_message "  -ui, --update-installer     Update Plane Installer" >&2
    show_message "  -h, --help                  Show help" >&2
    show_message "" >&2
    exit 1
    
}
function update_installer() {
    show_message "Updating Plane Installer ✋" >&2
    sudo curl -H 'Cache-Control: no-cache, no-store' \
        -s -o /usr/local/bin/plane-app  \
        https://raw.githubusercontent.com/$CODE_REPO/$DEPLOY_BRANCH/deploy/1-click/plane-app?token=$(date +%s) 

    sudo chmod +x /usr/local/bin/plane-app > /dev/null&> /dev/null
    show_message "Plane Installer Updated ✅" "replace_last_line" >&2
}

export DEPLOY_BRANCH=${BRANCH:-master}
export APP_RELEASE=$DEPLOY_BRANCH
export DOCKERHUB_USER=makeplane
export PULL_POLICY=always

if [ "$DEPLOY_BRANCH" == "master" ]; then
    export APP_RELEASE=latest
fi

PLANE_INSTALL_DIR=/opt/plane
DATA_DIR=$PLANE_INSTALL_DIR/data
LOG_DIR=$PLANE_INSTALL_DIR/logs
CODE_REPO=${GIT_REPO:-makeplane/plane}
OS_SUPPORTED=false
CPU_ARCH=$(uname -m)
PROGRESS_MSG=""
USE_GLOBAL_IMAGES=0
PACKAGE_MANAGER=""
MY_IP=$(curl -s ifconfig.me)

if [[ $CPU_ARCH == "amd64" || $CPU_ARCH == "x86_64" || ( $DEPLOY_BRANCH == "master" && ( $CPU_ARCH == "arm64" || $CPU_ARCH == "aarch64" ) ) ]]; then
    USE_GLOBAL_IMAGES=1
fi

sudo mkdir -p $PLANE_INSTALL_DIR/{data,log}

if command -v apt-get &> /dev/null; then
    PACKAGE_MANAGER="apt-get"
elif command -v yum &> /dev/null; then
    PACKAGE_MANAGER="yum"
elif command -v apk &> /dev/null; then
    PACKAGE_MANAGER="apk"
fi

if [ "$1" == "start" ]; then
    start_server
elif [ "$1" == "stop" ]; then
    stop_server
elif [ "$1" == "restart" ]; then
    restart_server
elif [ "$1" == "--install" ] || [ "$1" == "-i" ]; then
    install
    start_server
    show_message "" >&2
    show_message "To view help, use plane-app --help " >&2
elif [ "$1" == "--configure" ] || [ "$1" == "-c" ]; then
    configure_plane
    printUsageInstructions
elif [ "$1" == "--upgrade" ] || [ "$1" == "-up" ]; then
    upgrade
elif [ "$1" == "--uninstall" ] || [ "$1" == "-un" ]; then
    uninstall
elif [ "$1" == "--update-installer" ] || [ "$1" == "-ui" ]; then
    update_installer
elif [ "$1" == "--help" ] || [ "$1" == "-h" ]; then
    show_help
else
    show_help
fi
